package com.project.bo;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import com.project.bean.Features;
import com.project.bean.FinalProject;
import com.project.persistence.dao.FeaturesDAOImpl;
import com.project.structures.util.FileUtils;
import com.project.structures.util.JSONUtils;
import com.project.structures.util.XMLUtils;
import com.project.structures.xml.RuleXML;
import com.project.utils.Utils;

public class FeaturesBO {
	
	private static FeaturesBO instance;
	private static HashMap<Integer,Features> features = new HashMap<Integer, Features>();
		
	public static FeaturesBO getInstance() {
		if (instance == null) {
			instance = new FeaturesBO();
		}
		return instance;
	}
	
	private FeaturesBO() {
		
	}
	
	public List<Features> getFeatures() {
		
		if (features == null || features.size() <= 0) {
			FeaturesDAOImpl featuresDAO = new FeaturesDAOImpl();
			List<Features> features = featuresDAO.getAll();
			
			for(Features feature : features) {
				insertOnCache(feature);
			}
		}
		return new ArrayList<Features>(features.values()) ;
	}
	
	public List<Features> getFeaturesByRoleId(Integer roleId) {
		FeaturesDAOImpl featuresDAO = new FeaturesDAOImpl();
		return featuresDAO.getAllById(roleId);
	}
	
	public Boolean insert(Features feature) {
		FeaturesDAOImpl featuresDAO = new FeaturesDAOImpl();
		
		if(featuresDAO.insert(feature)) {
			//cria uma "rule" para o urlrewriter
			RuleXML rule = new RuleXML();
			rule.setFrom("(/"+feature.getFeatureLink()+")$");
			rule.setTo("contents/templates/features/" + feature.getFeatureLink() + ".jsp");
			
			//adiciona itens nas listas de XML e JSON
			FinalProject.getUrlrewriterNodes().addRule(rule);
			FinalProject.getFeaturesMAP().addFeature(feature);

			//Monta um JSP de exemplo
			String content = FinalProject.getExampleJSP();
			content = content.replace("#link#", feature.getFeatureLink());
			
			//Persiste os objetos nos arquivos e cria um jsp para o conteudo			
			JSONUtils.marshalToFile(FinalProject.getFeaturesMAP());
			XMLUtils.marshalToFile(FinalProject.getUrlrewriterNodes());
			FileUtils.writeFile(feature.getFeatureLink() + ".jsp", content);
			
			insertOnCache(feature);
		}
		
		return Boolean.TRUE;
	}
	
	public Boolean update(Features feature) {
		FeaturesDAOImpl featuresDAO = new FeaturesDAOImpl();
		Boolean result = featuresDAO.update(feature);
		
		if (result) {
			FinalProject.getFeaturesMAP().addFeature(feature);
			insertOnCache(feature);
		}
		
		return result;
	}
	
	public Boolean disable(Integer featureId) {
		Features feature = new Features();
		
		feature = features.get(featureId);
		feature.setActive(Boolean.FALSE);
		
		FeaturesDAOImpl featuresDAO = new FeaturesDAOImpl();
		Boolean result  = featuresDAO.disable(feature);
		
		if (result) {
			insertOnCache(feature);
		}
		
		return result;
	}
	
	
	public Boolean enable(Integer featureId) {
		Features feature = new Features();
		
		feature = features.get(featureId);
		feature.setActive(Boolean.TRUE);
		
		FeaturesDAOImpl featuresDAO = new FeaturesDAOImpl();
		Boolean result  = featuresDAO.enable(feature);
		
		if (result) {
			insertOnCache(feature);
		}
		
		return result;
	}
	
	public List<String> getFunctions(String link) {
		FeaturesDAOImpl featuresDAO = new FeaturesDAOImpl();
		return featuresDAO.getFeaturesFunctions(link);
	}
	
	
	private void insertOnCache(Features feature) {
		if (features != null) {
			features.put(feature.getFeatureId(), feature);
		}
		Utils.clearUserCache();
	}
	
	public static void clearCache() {
		features.clear();
		features = null;
		features = new HashMap<Integer, Features>();
	}
	
	public static void initializeCache() {
		FeaturesBO.getInstance().getFeatures();
	}
}
